using System;
using System.Globalization;
using System.IO;
using System.Threading;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using Nop.Core;
using Nop.Core.Data;
using Nop.Core.Infrastructure;
using Nop.Services.Logging;

namespace Spotshub.Api
{
    public class WebApiApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            SpotshubConfig.Initialize();
            AreaRegistration.RegisterAllAreas();
            GlobalConfiguration.Configure(WebApiConfig.Register);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
        }

        protected void Application_BeginRequest(object sender, EventArgs e)
        {
            //ignore static resources
            var webHelper = EngineContext.Current.Resolve<IWebHelper>();
            if (webHelper.IsStaticResource(this.Request))
                return;

            //keep alive page requested (we ignore it to prevent creating a guest customer records)
            //string keepAliveUrl = string.Format("{0}keepalive", webHelper.GetStoreLocation());
            //if (webHelper.GetThisPageUrl(false).StartsWith(keepAliveUrl, StringComparison.InvariantCultureIgnoreCase))
            //    return;

            if (!DataSettingsHelper.DatabaseIsInstalled())
                return;

            //miniprofiler
            //if (EngineContext.Current.Resolve<StoreInformationSettings>().DisplayMiniProfilerInPublicStore)
            //{
            //    //MiniProfiler.Start();
            //    //store a value indicating whether profiler was started
            //    //HttpContext.Current.Items["spotshub.MiniProfilerStarted"] = true;
            //}
            //ILog _logService = LogManager.GetInstance().GetILog();
            //ILogger _logger = new DefaultLogger();
        }

		protected void Application_LogRequest(object sender, EventArgs e)
		{
			HttpApplication app = (HttpApplication)sender;
			HttpContext context = app.Context;

			var ILogger = EngineContext.Current.Resolve<ILogger>();

			var url = context.Request.Url;
			var method = context.Request.HttpMethod;
			var Headers = context.Request.Headers.AllKeys;
			if (Headers != null)
			{
				var strHeard = "Url:" + url + ";";
				strHeard += "Method:" + method + ";";
				foreach (var oneheader in Headers)
				{
					var key = oneheader;
					var value = context.Request.Headers.Get(key);
					strHeard += key + ":" + value + ";";
				}
				var stream = context.Request.InputStream;
				stream.Position = 0;
				var reader = new StreamReader(stream);
				var content = reader.ReadToEnd();
				strHeard += ";UserWrite:" + content;
				stream.Position = 0;
				//_logService.Debug(strHeard);
				ILogger.InsertLog(Nop.Core.Domain.Logging.LogLevel.Information, "Mobile phone APP requests", strHeard);
			}
		}

        protected void Application_EndRequest(object sender, EventArgs e)
        {
            //miniprofiler
            //var miniProfilerStarted = HttpContext.Current.Items.Contains("spotshub.MiniProfilerStarted") &&
            //     Convert.ToBoolean(HttpContext.Current.Items["spotshub.MiniProfilerStarted"]);
            //if (miniProfilerStarted)
            //{
            //    MiniProfiler.Stop();
            //}
        }

        protected void Application_AuthenticateRequest(object sender, EventArgs e)
        {
            //we don't do it in Application_BeginRequest because a user is not authenticated yet
            SetWorkingCulture();
        }

        protected void Application_Error(Object sender, EventArgs e)
        {
            var exception = Server.GetLastError();
            //disable compression (if enabled). More info - http://stackoverflow.com/questions/3960707/asp-net-mvc-weird-characters-in-error-page
            //log error
            LogException(exception);

            //process 404 HTTP errors
            //var httpException = exception as HttpException;
            //if (httpException != null && httpException.GetHttpCode() == 404)
            //{
            //    var webHelper = EngineContext.Current.Resolve<IWebHelper>();
            //    if (!webHelper.IsStaticResource(this.Request))
            //    {
            //        Response.Clear();
            //        Server.ClearError();
            //        Response.TrySkipIisCustomErrors = true;

            //        // Call target Controller and pass the routeData.
            //        IController errorController = EngineContext.Current.Resolve<Nop.Web.Controllers.CommonController>();

            //        var routeData = new RouteData();
            //        routeData.Values.Add("controller", "Common");
            //        routeData.Values.Add("action", "PageNotFound");

            //        errorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
            //    }
            //}
        }

        protected void SetWorkingCulture()
        {
            if (!DataSettingsHelper.DatabaseIsInstalled())
                return;

            var webHelper = EngineContext.Current.Resolve<IWebHelper>();
            if (webHelper.IsStaticResource(this.Request))
                return;

            //keep alive page requested (we ignore it to prevnt creating a guest customer records)
            string keepAliveUrl = string.Format("{0}keepalive", webHelper.GetStoreLocation());
            if (webHelper.GetThisPageUrl(false).StartsWith(keepAliveUrl, StringComparison.InvariantCultureIgnoreCase))
                return;


            if (webHelper.GetThisPageUrl(false).StartsWith(string.Format("{0}admin", webHelper.GetStoreLocation()),
                StringComparison.InvariantCultureIgnoreCase))
            {
                //admin area

                //always set culture to 'en-US'
                //we set culture of admin area to 'en-US' because current implementation of Telerik grid 
                //doesn't work well in other cultures
                //e.g., editing decimal value in russian culture
                var culture = new CultureInfo("en-US");
                Thread.CurrentThread.CurrentCulture = culture;
                Thread.CurrentThread.CurrentUICulture = culture;
            }
            else
            {
                //public store
                var workContext = EngineContext.Current.Resolve<IWorkContext>();
                var culture = new CultureInfo(workContext.WorkingLanguage.LanguageCulture);
                Thread.CurrentThread.CurrentCulture = culture;
                Thread.CurrentThread.CurrentUICulture = culture;
            }
        }

        protected void LogException(Exception exc)
        {
            if (exc == null)
                return;

            if (!DataSettingsHelper.DatabaseIsInstalled())
                return;

            //ignore 404 HTTP errors
            var httpException = exc as HttpException;
            if (httpException != null && httpException.GetHttpCode() == 404 &&
                !EngineContext.Current.Resolve<Nop.Core.Domain.Common.CommonSettings>().Log404Errors)
                return;

            try
            {
                var logger = EngineContext.Current.Resolve<ILogger>();
                var workContext = EngineContext.Current.Resolve<IWorkContext>();
                logger.Error(exc.Message, exc, workContext.CurrentCustomer);
            }
            catch (Exception)
            {
                //don't throw new exception if occurs
            }
        }

    }
}
